package com.digipepper;

/*
http://d.hatena.ne.jp/yamashina/20090613/1244901811
*/

import java.util.List;
import java.util.ArrayList;
//import java.util.Random;

import _root_.android.util.{DisplayMetrics,Log};
import _root_.android.os.{Handler,Bundle};
import _root_.android.app.Activity;
import _root_.android.content.Context;
import _root_.android.view.{MotionEvent,View};
import _root_.android.view.{Window,WindowManager};
import _root_.android.view.{Menu,MenuItem,MenuInflater};
import _root_.android.graphics.{Canvas,Color,Paint};
import _root_.android.graphics.Paint.Style;
import _root_.android.hardware.{Sensor,SensorEvent,SensorEventListener,SensorManager};

import ape.APEngine;
import ape.AbstractParticle;
import ape.CircleParticle;
import ape.RectangleParticle;
import ape.SpringConstraint;
import ape.Vector;
import ape.WheelParticle;

import scala.util.Random;

class PhysicsWorld(context:Context, W:Int, H:Int) extends View(context) {

	val targetFPS:Int = 40;
	val timeStep:Float = 22.0f / targetFPS;
	val keySpeed:Float = 0.2f;
	var paintQueue:ArrayList[Any] = null;
	var TEXT_SIZE:Int = 16;

	val objRandom = new Random();

  var paint:Paint = new Paint();
  paint.setStyle(Style.STROKE);
  paint.setColor(Color.RED);
         
	//var APEngine:APEngine = new APEngine();
	APEngine.init(1.0f/2);
	APEngine.setCollisionResponseMode(APEngine.SELECTIVE);
	APEngine.addMasslessForce(new Vector(0.0f, 3.0f));

	var floor:RectangleParticle = new RectangleParticle(paint,(W/2).asInstanceOf[Float],(H-25-1).asInstanceOf[Float],(W-1).asInstanceOf[Float],50.0f, 0.0f, true, 1.0f, 0.3f, 0.0f);
	APEngine.addParticle(floor);

	var floorRightAngle:RectangleParticle = new RectangleParticle(paint,180.0f, 100.0f, 120.0f,20.0f, 0.5f,true,1.0f,0.3f,0.0f);
	APEngine.addParticle(floorRightAngle);

	var floorLeftAngle:RectangleParticle = new RectangleParticle(paint,50.0f, 390.0f, 120.0f,20.0f, 0.5f,true,1.0f,0.3f,0.0f);
	APEngine.addParticle(floorLeftAngle);

	var leftWall:RectangleParticle = new RectangleParticle(paint,14.0f,200.0f,30.0f,500.0f,0.0f,true,1.0f,0.3f,0.0f);
	APEngine.addParticle(leftWall);

	var rightWall:RectangleParticle = new RectangleParticle(paint,310.0f,180.0f,30.0f,500.0f,0.0f,true,1.0f,0.3f,0.0f);
	APEngine.addParticle(rightWall);

	// little boxes
	var intTmp = 0;
	while(intTmp < 9){
		var px:Float = (7 * intTmp) + 60;
		APEngine.addParticle(new RectangleParticle(paint, px, 200.0f, 10, 5f, objRandom.nextFloat()*200.0f,false,1.8f,0.1f,0.0f));
		APEngine.addParticle(new CircleParticle(paint,px+40.0f,objRandom.nextFloat()*210.0f,3.5f,false,1.8f,0.1f,0.0f));
		intTmp = intTmp + 1;
	}

	// 操作用のエンを作成
	var objCrcl = new CircleParticle(paint, 30.0f, 110.0f, 30.0f, false,1.8f,0.1f,0.0f);
	APEngine.addParticle(objCrcl);

	paintQueue = APEngine.getAll().asInstanceOf[ArrayList[Any]];

	def setCrclXY(x:Float, y:Float) {
		objCrcl.curr.x = x;
		objCrcl.curr.y = y;
	}

	def getCrclXY:Tuple2[Float,Float] = {
		new Tuple2[Float, Float](objCrcl.curr.x, objCrcl.curr.y);
	}

	var touchX = 0;
	var touchY = 0;
  var touchAction:Int = 0;

	override def onTouchEvent(event:MotionEvent):Boolean={
		touchX = event.getX().asInstanceOf[Int];
		touchY = event.getY().asInstanceOf[Int];
		touchAction = event.getAction();

/*
		if ( myCircle.isInnerCircle(touchX, touchY) == true ) {
			if (touchAction == MotionEvent.ACTION_MOVE) {
				myCircle.moveTo(touchX, touchY);
			}
		}
*/

		if ( (objCrcl.curr.x - objCrcl.getRadius() <= touchX) && (touchX <= objCrcl.curr.x + objCrcl.getRadius()) ) {
			if ( (objCrcl.curr.y - objCrcl.getRadius() <= touchY) && (touchY <= objCrcl.curr.y + objCrcl.getRadius()) ) {
				setCrclXY(touchX.asInstanceOf[Float], touchY.asInstanceOf[Float]);
			}
		}

		invalidate();
		true;
	}

	override def onDraw(canvas:Canvas) {

		APEngine.setDefaultContainer(canvas);
		var i = 0;
		while(i < paintQueue.size()) {
			if (paintQueue.get(i).isInstanceOf[RectangleParticle])
				(paintQueue.get(i).asInstanceOf[RectangleParticle]).paint();
			else if (paintQueue.get(i).isInstanceOf[CircleParticle]) 
				(paintQueue.get(i).asInstanceOf[CircleParticle]).paint();
			else if (paintQueue.get(i).isInstanceOf[SpringConstraint]) 
				(paintQueue.get(i).asInstanceOf[SpringConstraint]).paint();				
			i = i + 1;
    }

		// draw touch position
		canvas.drawText("Touch (x,y) = ("+touchX+","+touchY+")", 0, TEXT_SIZE, paint);
		canvas.drawText("Circle (x,y) = ("+objCrcl.curr.x.toInt+","+objCrcl.curr.y.toInt+")", 0, TEXT_SIZE*3, paint);

		if(objCrcl.curr.y < -1000.0 || objCrcl.curr.y > 1000.0){
			objCrcl.curr.y = 0.0f;
		}

		paint.setStyle(Paint.Style.FILL_AND_STROKE);
//		paint.setColor(myCircle.getColor());
//		canvas.drawCircle(myCircle.getX(), myCircle.getY(), myCircle.getR(), paint);
  }

  def update() {
	   APEngine.step();
// ぐるぐるしてる棒用
//	   rotatingRect.setRotation(rotatingRect.getRotation() + 0.03f);
     invalidate();
   }
}

// --
class MoveCircle extends Activity with SensorEventListener {

//  var touchView:TouchView = null;
		var orientationSensor:Sensor = null;
		var accelerometerSensor:Sensor = null;

    var mWorld:PhysicsWorld = null;
    var mHandler:Handler = null;

    override def onCreate(savedInstanceState:Bundle) {
    	//info: http://developer.android.com/guide/developing/tools/traceview.html
    	// start tracing to "/sdcard/testape2d.trace"

      super.onCreate(null);
			val TEXT_SIZE = 16;

			var paint:Paint = new Paint();
			paint.setAntiAlias(true);
			paint.setTextSize(TEXT_SIZE);
			paint.setColor(0xFFFFFFFF);

			var sm:SensorManager = getSystemService(Context.SENSOR_SERVICE).asInstanceOf[SensorManager];
			var sensorList:List[Sensor] = null;

			// センサーの取得1
			sensorList = sm.getSensorList(Sensor.TYPE_ORIENTATION);
			orientationSensor = sensorList.get(0);

			// センサーの取得2
			sensorList = sm.getSensorList(Sensor.TYPE_ACCELEROMETER);
			accelerometerSensor = sensorList.get(0);

			sm.registerListener(this, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL);
			sm.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);

      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
      // this.requestWindowFeature(Window.FEATURE_NO_TITLE);

      var dm:DisplayMetrics = new DisplayMetrics();
      getWindowManager().getDefaultDisplay().getMetrics(dm);

      mWorld = new PhysicsWorld(this, dm.widthPixels, dm.heightPixels);
      this.setContentView(this.mWorld);

      // Start Regular Update

      mHandler = new Handler();
      mHandler.post(update);
    }

	def onSensorChanged(event:SensorEvent) {
		if (event.sensor == orientationSensor) {
			Log.d("SENSOR","orientationSensor("+event.values(2)+","+event.values(1)+")");
			val DELTA:Int = 7;
			val ALLOWANCE:Int = 10;
			var xy:Tuple2[Float,Float] = mWorld.getCrclXY;
			var x:Float = xy._1;
			var y:Float = xy._2;
			
			if (event.values(2) < ALLOWANCE*(-1)) {
				x += DELTA;
			}
			else if (event.values(2) > ALLOWANCE) {
				x -= DELTA;
			}

			if (event.values(1) < ALLOWANCE*(-1)) {
				y += DELTA;
			}
			else if (event.values(1) > ALLOWANCE) {
				y -= DELTA;
			}
			//myCircle.moveTo(x, y);
			//touchView.invalidate();
			mWorld.setCrclXY(x, y);
		}
		else if (event.sensor == accelerometerSensor) {
			// Log.d("SENSOR","accelerometerSensor"+event.values.toString);
		}
	}
	def onAccuracyChanged(event:SensorEvent, i:Int) {
	}

  override def onPause() {
    super.onPause();
    mHandler.removeCallbacks(update);
  }

    var update:Runnable = new Runnable() {
      def run() {
        mWorld.update();
        mHandler.postDelayed(update, 1);
      }
    };

    override def onResume()
    {
      super.onResume();
    }
   
    override def onStop()
    {
      super.onStop();
      System.exit(0);
    }

	// 終了メニューを作成1
	override def onCreateOptionsMenu(menu:Menu):Boolean = {
		var inflater:MenuInflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);

		true;
	}

	// 終了メニューを作成2
	override def onMenuItemSelected(featureId:Int, item:MenuItem):Boolean = {
		var id:Int = item.getItemId();

		//XML中のメニューボタンにアクセスするにはR.id以下を利用する
		if (id == R.id.End) {
/*
・Log.e()：エラー
・Log.w()：警告
・Log.i()：情報
・Log.d()：デバッグ
・Log.v()：冗長
*/
			//TODO 再検索
			Log.d("Menu", "itemId: 0");
			finish();
		}

		true;
	}
	def onAccuracyChanged(sensor:Sensor, accuracy:Int) {
	}
}
// --
